package com.mydom4j.prod;

import com.mydom4j.util.DomWrite;
import org.dom4j.Attribute;
import org.dom4j.CDATA;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentFactory;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.io.OutputFormat;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by wuxia on 2016/8/21 0021.
 */
public class CreateSpringModelXML {
    private static final String SPRING_DEFALT_NAMESPACE = "http://www.springframework.org/schema/beans";
    private static final String SPRING_XSI_NAMESPACE = "http://www.w3.org/2001/XMLSchema-instance";
    private static final String  SPRING_XSI_SCHEMALOCATION = "http://www.springframework.org/schema/beans " +
            "http://www.springframework.org/schema/beans/spring-beans.xsd";

    public static void main(String[] args) {
        CreateSimpleXML.simpleWriteDocument("C:/Users/wuxia/Desktop/spring.xml", createSpringModelXml());
        /**
         * XML 格式太丑？ 没关系我们现在有格式化的了
         */
//        DomWrite.writeDocument("C:/Users/wuxia/Desktop/spring.xml", createSpringModelXml());
//        consoleOut();
    }

    /**
     * 可以把内容输出到控制台 而不是 文件吗？ 当然可以
     */
    public static void consoleOut() {
        /**
         * 简化格式
         */
        OutputFormat format = OutputFormat.createCompactFormat();
        /**
         * XML格式
         */
        format.setEncoding("GBK");
        DomWrite.writeDocument(System.out, createSpringModelXml(), format);
    }

    /**
     * 创建一个类似Spring XMl的文件
     * @return
     */
    public static Document createSpringModelXml() {
        Document document = CreateSimpleXML.createSimpleDocument();
        // 创建根节点
        Element root = DocumentHelper.createElement("beans");

        // 给根节点添加一些属性
        List<Element> list = new ArrayList<>();

        addNameSpace(root);

        // 再加点属性
        root.addAttribute("xsi:schemaLocation", SPRING_XSI_SCHEMALOCATION);

        list.add(buildUserBean());
        list.add(buildItemBean());
        list.add(buildCdataBean());
        list.forEach(p -> root.add(p));
        buildBookElement().forEach(p -> root.add(p));
        document.setRootElement(root);
        return document;
    }

    /**
     * 添加NameSpace
     * @param element
     */
    private static void addNameSpace(Element element) {
        /**
         * xmlns 是xmlNameSpace的关键字， 直接用xmlns会无效
         * 这里为什么加了 \t ？ 其实是因为 DocumentHelper 的createElement存在缺陷
         * 缺陷是无法指定 namespaceURI
         *
         *
         */
//        Attribute xmlns = DocumentHelper.createAttribute(element, "\txmlns", "http://www.springframework.org/schema/beans");
        /*
        List list = new ArrayList();
        list.add(xmlns);
        element.setAttributes(list);
        */
        /**
         * 当然nameSpace不应该这么指定
         * dom4j 希望通过这种方式指定namespace
         */

//        element.add(xmlns);

//        element.addNamespace("", SPRING_DEFALT_NAMESPACE);
        Namespace nameSpace = DocumentHelper.createNamespace("", SPRING_DEFALT_NAMESPACE);
        element.add(nameSpace);
        element.addNamespace("xsi",SPRING_XSI_NAMESPACE);
    }

    /**
     * 构建UserBean
     * @return
     */
    private static Element buildUserBean() {
        DocumentFactory documentFactory = DocumentFactory.getInstance();
        /**
         * 可以看到 DucumentFactory 的 createElement 就能指定namespaceURI
         * 所以 如果需要xmlns的地方 尽量使用 DocumentFactory
         */
        // userBean
        Element userBean = documentFactory.createElement("bean", "just for test name space");
        userBean.addAttribute("id", "user");
        userBean.addAttribute("class", "com.test.user");
        return userBean;
    }

    /**
     * 构建ItemBean
     * @return
     */
    private static Element buildItemBean() {
        // itemBean
        Element itemBean = DocumentHelper.createElement("bean");
        itemBean.addAttribute("id", "item");
        itemBean.addAttribute("class", "com.test.item");
        Element prop = DocumentHelper.createElement("property");
        prop.setName("prefix");
        prop.addAttribute("value", "/");
        itemBean.add(prop);
        return itemBean;
    }

    /**
     * 构建CDataBean
     * @return
     */
    private static Element buildCdataBean() {
        // 还有CDATA是吧？
        Element cdataEle = DocumentHelper.createElement("cdata");
        CDATA cdata = DocumentHelper.createCDATA("select * from item where itemId <> 1");
        cdataEle.addAttribute("id", "cdata");
        cdataEle.add(cdata);
        /**
         * ？？？？？
         * 不知道为啥 root add了Namespace 之后 所有子节点都会带上 而且remove不掉 不过不要在意这些细节 影响不大
         */
        cdataEle.remove(cdataEle.getNamespace());
        return cdataEle;
    }

    /**
     * 构架Book元素
     * @return
     */
    private static List<Element> buildBookElement() {
        List<Element> books = new ArrayList();

        Element itemNameBean = DocumentHelper.createElement("bean");
        List<Attribute> attributes = new ArrayList();
        attributes.add(DocumentHelper.createAttribute(itemNameBean, "name", "item"));
        attributes.add(DocumentHelper.createAttribute(itemNameBean, "value", "3"));
        attributes.add(DocumentHelper.createAttribute(itemNameBean, "price", "35"));
        itemNameBean.setAttributes(attributes);
        itemNameBean.setText("value test 35");

        try {
            books.add(itemNameBean);
            books.add(DocumentHelper.parseText("<bean xmlns=\"\" name=\"book\" value=\"1\" price=\"36\">value test 36</bean>").getRootElement());
            books.add(DocumentHelper.parseText("<bean xmlns=\"\" name=\"book\" value=\"1\" price=\"37\">value test 37</bean>").getRootElement());
            books.add(DocumentHelper.parseText("<bean xmlns=\"\" name=\"book\" value=\"1\" price=\"38\">value test 38</bean>").getRootElement());
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        return books;
    }

    /**
     * 好了现在创建一个XML文件已经完全没有问题了 接下来就开始解析XML吧
     */
}
